{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "h3z5i2X45vTk"
   },
   "source": [
    "### Geospatial Recommendation System\n",
    "\n",
    "![image-for-the-concept](https://github.com/lancedb/vectordb-recipes/blob/main/examples/Geospatial-Recommendation-System/Geospatial%20Recommendation%20System.png?raw=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "BHGgH_UH5vTl"
   },
   "source": [
    "In this tutorial, we'll enhance our restaurant recommendation system using Full Text Search (FTS) Indexes and Geospatial APIs.\n",
    "\n",
    "1. Extract User Preferences: Identify key details from user input such as preferred cuisines and location.\n",
    "2. Construct Query String: Synthesize these details into a structured query string for searching.\n",
    "3. Perform FTS Index Search: Use the query string to find relevant restaurant recommendations.\n",
    "4. Apply Geospatial Filtering: Use a Geospatial API to locate the user and refine recommendations based on proximity.\n",
    "\n",
    "We can enhance later on by adding a filter to sort the recommendations based on distance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "a0k_ssua5vTn"
   },
   "source": [
    "### Importing the relevant libraires"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "id": "A9QFbWf05yUT"
   },
   "outputs": [],
   "source": [
    "%%capture\n",
    "!pip install lancedb pandas sentence-transformers requests openai tantivy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "tFWV_ONGB2qN",
    "outputId": "1b1cb49b-63d9-41c5-ea37-99e1446474b5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--2025-01-05 10:34:14--  https://drive.google.com/uc?export=download&id=17Div0ml4Nelr1C4QaGVJzC7lnMx--BkM\n",
      "Resolving drive.google.com (drive.google.com)... 74.125.126.139, 74.125.126.138, 74.125.126.102, ...\n",
      "Connecting to drive.google.com (drive.google.com)|74.125.126.139|:443... connected.\n",
      "HTTP request sent, awaiting response... 303 See Other\n",
      "Location: https://drive.usercontent.google.com/download?id=17Div0ml4Nelr1C4QaGVJzC7lnMx--BkM&export=download [following]\n",
      "--2025-01-05 10:34:14--  https://drive.usercontent.google.com/download?id=17Div0ml4Nelr1C4QaGVJzC7lnMx--BkM&export=download\n",
      "Resolving drive.usercontent.google.com (drive.usercontent.google.com)... 74.125.202.132, 2607:f8b0:4001:c06::84\n",
      "Connecting to drive.usercontent.google.com (drive.usercontent.google.com)|74.125.202.132|:443... connected.\n",
      "HTTP request sent, awaiting response... 200 OK\n",
      "Length: 883287 (863K) [application/octet-stream]\n",
      "Saving to: ‘data.csv’\n",
      "\n",
      "data.csv            100%[===================>] 862.58K  --.-KB/s    in 0.007s  \n",
      "\n",
      "2025-01-05 10:34:17 (121 MB/s) - ‘data.csv’ saved [883287/883287]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "!wget --no-check-certificate 'https://drive.google.com/uc?export=download&id=17Div0ml4Nelr1C4QaGVJzC7lnMx--BkM' -O data.csv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 310
    },
    "id": "0-KnjGti5vTn",
    "outputId": "f54bfd38-dd7d-4cff-ef57-9bbf53d41441"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.google.colaboratory.intrinsic+json": {
       "summary": "{\n  \"name\": \"restaurant_data\",\n  \"rows\": 8679,\n  \"fields\": [\n    {\n      \"column\": \"Area\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 833,\n        \"samples\": [\n          \"Lakdi Ka Pul\",\n          \"Umra Jakat\",\n          \"Salt Lake Area\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"City\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 9,\n        \"samples\": [\n          \"Ahmedabad\",\n          \"Hyderabad\",\n          \"Delhi\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Restaurant\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 7865,\n        \"samples\": [\n          \"Sri Radhe Chills And Thrills\",\n          \"Rcb Bar & Cafe\",\n          \"Momo Nation Cafe\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Price\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 230.9379787288186,\n        \"min\": 0.0,\n        \"max\": 2500.0,\n        \"num_unique_values\": 120,\n        \"samples\": [\n          0.0,\n          140.0,\n          800.0\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Avg ratings\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 0.6476154836286703,\n        \"min\": 2.0,\n        \"max\": 5.0,\n        \"num_unique_values\": 30,\n        \"samples\": [\n          5.0,\n          3.5,\n          2.7\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Total ratings\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 391,\n        \"min\": 20,\n        \"max\": 10000,\n        \"num_unique_values\": 8,\n        \"samples\": [\n          500,\n          5000,\n          100\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Food type\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 3734,\n        \"samples\": [\n          \"Punjabi,Thalis,North Indian,Tandoor,Snacks\",\n          \"Gujarati,North Indian,Thalis\",\n          \"Street Food,Fast Food,Snacks,Beverages\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Address\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 2339,\n        \"samples\": [\n          \"Bheemanna Garden St Sri Ram Nagar\",\n          \"Shiva Road Sector 7\",\n          \"Oposite Hedua Park\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Delivery time\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 14,\n        \"min\": 20,\n        \"max\": 109,\n        \"num_unique_values\": 81,\n        \"samples\": [\n          35,\n          59,\n          37\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    }\n  ]\n}",
       "type": "dataframe",
       "variable_name": "restaurant_data"
      },
      "text/html": [
       "\n",
       "  <div id=\"df-686eecb4-4e8c-4947-bc2b-3f278d61c3a1\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Area</th>\n",
       "      <th>City</th>\n",
       "      <th>Restaurant</th>\n",
       "      <th>Price</th>\n",
       "      <th>Avg ratings</th>\n",
       "      <th>Total ratings</th>\n",
       "      <th>Food type</th>\n",
       "      <th>Address</th>\n",
       "      <th>Delivery time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Koramangala</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Tandoor Hut</td>\n",
       "      <td>300.0</td>\n",
       "      <td>4.4</td>\n",
       "      <td>100</td>\n",
       "      <td>Biryani,Chinese,North Indian,South Indian</td>\n",
       "      <td>5Th Block</td>\n",
       "      <td>59</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Koramangala</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Tunday Kababi</td>\n",
       "      <td>300.0</td>\n",
       "      <td>4.1</td>\n",
       "      <td>100</td>\n",
       "      <td>Mughlai,Lucknowi</td>\n",
       "      <td>5Th Block</td>\n",
       "      <td>56</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Jogupalya</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Kim Lee</td>\n",
       "      <td>650.0</td>\n",
       "      <td>4.4</td>\n",
       "      <td>100</td>\n",
       "      <td>Chinese</td>\n",
       "      <td>Double Road</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Indiranagar</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>New Punjabi Hotel</td>\n",
       "      <td>250.0</td>\n",
       "      <td>3.9</td>\n",
       "      <td>500</td>\n",
       "      <td>North Indian,Punjabi,Tandoor,Chinese</td>\n",
       "      <td>80 Feet Road</td>\n",
       "      <td>57</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Indiranagar</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Nh8</td>\n",
       "      <td>350.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>50</td>\n",
       "      <td>Rajasthani,Gujarati,North Indian,Snacks,Desser...</td>\n",
       "      <td>80 Feet Road</td>\n",
       "      <td>63</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-686eecb4-4e8c-4947-bc2b-3f278d61c3a1')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-686eecb4-4e8c-4947-bc2b-3f278d61c3a1 button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-686eecb4-4e8c-4947-bc2b-3f278d61c3a1');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-82fd8098-5d67-4c45-bebe-97f43d3c1af8\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-82fd8098-5d67-4c45-bebe-97f43d3c1af8')\"\n",
       "            title=\"Suggest charts\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-82fd8098-5d67-4c45-bebe-97f43d3c1af8 button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "\n",
       "    </div>\n",
       "  </div>\n"
      ],
      "text/plain": [
       "          Area       City         Restaurant  Price  Avg ratings  \\\n",
       "0  Koramangala  Bangalore        Tandoor Hut  300.0          4.4   \n",
       "1  Koramangala  Bangalore      Tunday Kababi  300.0          4.1   \n",
       "2    Jogupalya  Bangalore            Kim Lee  650.0          4.4   \n",
       "3  Indiranagar  Bangalore  New Punjabi Hotel  250.0          3.9   \n",
       "4  Indiranagar  Bangalore                Nh8  350.0          4.0   \n",
       "\n",
       "   Total ratings                                          Food type  \\\n",
       "0            100          Biryani,Chinese,North Indian,South Indian   \n",
       "1            100                                   Mughlai,Lucknowi   \n",
       "2            100                                            Chinese   \n",
       "3            500               North Indian,Punjabi,Tandoor,Chinese   \n",
       "4             50  Rajasthani,Gujarati,North Indian,Snacks,Desser...   \n",
       "\n",
       "        Address  Delivery time  \n",
       "0     5Th Block             59  \n",
       "1     5Th Block             56  \n",
       "2   Double Road             50  \n",
       "3  80 Feet Road             57  \n",
       "4  80 Feet Road             63  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import lancedb\n",
    "import pandas as pd\n",
    "\n",
    "restaurant_data = pd.read_csv(\"data.csv\")\n",
    "restaurant_data = restaurant_data[restaurant_data.columns[1:]]\n",
    "restaurant_data.dropna(inplace=True)\n",
    "restaurant_data.drop_duplicates(inplace=True)\n",
    "restaurant_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "PTSumB1b5vTo"
   },
   "source": [
    "### Embedding the relevant parts of the data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "jcVaV65s5vTp"
   },
   "source": [
    "We will extract key information from the restaurant dataset columns and create a query string. This string will be encoded using our embedding model and then combined with additional data for storage in the Vector Database."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "5FUfug2G5vTp",
    "outputId": "57b00934-da22-44d1-ff2b-15e8531231db"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.10/dist-packages/sentence_transformers/SentenceTransformer.py:195: FutureWarning: The `use_auth_token` argument is deprecated and will be removed in v4 of SentenceTransformers.\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from sentence_transformers import SentenceTransformer\n",
    "from huggingface_hub import hf_hub_download\n",
    "\n",
    "os.environ[\"HUGGING_FACE_HUB_TOKEN\"] = \"****\"\n",
    "\n",
    "model = SentenceTransformer(\"paraphrase-MiniLM-L6-v2\", use_auth_token=True)\n",
    "data_points_vectors = []\n",
    "\n",
    "for _, row in restaurant_data.iterrows():\n",
    "    filter_cols = [\"Food type\", \"Avg ratings\", \"Address\"]\n",
    "    data_point = \"#\".join(f\"{col}/{row[col]}\" for col in filter_cols)\n",
    "    data_points_vectors.append(data_point)\n",
    "\n",
    "# Add the new column to the DataFrame\n",
    "restaurant_data[\"query_string\"] = data_points_vectors\n",
    "\n",
    "list_of_payloads = []\n",
    "\n",
    "for index, row in restaurant_data.iterrows():\n",
    "    encoded_vector = model.encode(row[\"query_string\"])\n",
    "    payload = {\n",
    "        \"Area\": row[\"Area\"],\n",
    "        \"City\": row[\"City\"],\n",
    "        \"Restaurant\": row[\"Restaurant\"],\n",
    "        \"Price\": row[\"Price\"],\n",
    "        \"Avg_ratings\": row[\"Avg ratings\"],\n",
    "        \"Total_ratings\": row[\"Total ratings\"],\n",
    "        \"Food_type\": row[\"Food type\"],\n",
    "        \"Address\": row[\"Address\"],\n",
    "        \"Delivery_time\": row[\"Delivery time\"],\n",
    "        \"query_string\": row[\"query_string\"],\n",
    "        \"vector\": encoded_vector,\n",
    "    }\n",
    "\n",
    "    list_of_payloads.append(payload)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "jb9pMFm45vTq"
   },
   "source": [
    "### Using the LanceDB database"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "V1XxLYrB5vTq"
   },
   "outputs": [],
   "source": [
    "# Connect to the LanceDB instance\n",
    "uri = \"data\"\n",
    "db = lancedb.connect(uri)\n",
    "\n",
    "lancedb_table = db.create_table(\"restaurant-geocoding-app\", data=list_of_payloads)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 487
    },
    "id": "_RTMOwEr5vTr",
    "outputId": "7645d5b2-43ea-4d0c-e57c-5771a1f4216c"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.google.colaboratory.intrinsic+json": {
       "summary": "{\n  \"name\": \"df\",\n  \"rows\": 8679,\n  \"fields\": [\n    {\n      \"column\": \"Area\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 833,\n        \"samples\": [\n          \"Lakdi Ka Pul\",\n          \"Umra Jakat\",\n          \"Salt Lake Area\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"City\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 9,\n        \"samples\": [\n          \"Ahmedabad\",\n          \"Hyderabad\",\n          \"Delhi\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Restaurant\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 7865,\n        \"samples\": [\n          \"Sri Radhe Chills And Thrills\",\n          \"Rcb Bar & Cafe\",\n          \"Momo Nation Cafe\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Price\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 230.9379787288186,\n        \"min\": 0.0,\n        \"max\": 2500.0,\n        \"num_unique_values\": 120,\n        \"samples\": [\n          0.0,\n          140.0,\n          800.0\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Avg_ratings\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 0.6476154836286703,\n        \"min\": 2.0,\n        \"max\": 5.0,\n        \"num_unique_values\": 30,\n        \"samples\": [\n          5.0,\n          3.5,\n          2.7\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Total_ratings\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 391,\n        \"min\": 20,\n        \"max\": 10000,\n        \"num_unique_values\": 8,\n        \"samples\": [\n          500,\n          5000,\n          100\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Food_type\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 3734,\n        \"samples\": [\n          \"Punjabi,Thalis,North Indian,Tandoor,Snacks\",\n          \"Gujarati,North Indian,Thalis\",\n          \"Street Food,Fast Food,Snacks,Beverages\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Address\",\n      \"properties\": {\n        \"dtype\": \"category\",\n        \"num_unique_values\": 2339,\n        \"samples\": [\n          \"Bheemanna Garden St Sri Ram Nagar\",\n          \"Shiva Road Sector 7\",\n          \"Oposite Hedua Park\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Delivery_time\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 14,\n        \"min\": 20,\n        \"max\": 109,\n        \"num_unique_values\": 81,\n        \"samples\": [\n          35,\n          59,\n          37\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"query_string\",\n      \"properties\": {\n        \"dtype\": \"string\",\n        \"num_unique_values\": 8231,\n        \"samples\": [\n          \"Food type/Chinese,Indian#Avg ratings/3.7#Address/Rohini\",\n          \"Food type/North Indian,Biryani,Chinese#Avg ratings/3.9#Address/Nampally\",\n          \"Food type/North Indian,South Indian,Chinese,Continental,Punjabi#Avg ratings/4.1#Address/Warje\"\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"vector\",\n      \"properties\": {\n        \"dtype\": \"object\",\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    }\n  ]\n}",
       "type": "dataframe",
       "variable_name": "df"
      },
      "text/html": [
       "\n",
       "  <div id=\"df-3af99ccc-6a14-4435-a666-dc6f231b349e\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Area</th>\n",
       "      <th>City</th>\n",
       "      <th>Restaurant</th>\n",
       "      <th>Price</th>\n",
       "      <th>Avg_ratings</th>\n",
       "      <th>Total_ratings</th>\n",
       "      <th>Food_type</th>\n",
       "      <th>Address</th>\n",
       "      <th>Delivery_time</th>\n",
       "      <th>query_string</th>\n",
       "      <th>vector</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Koramangala</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Tandoor Hut</td>\n",
       "      <td>300.0</td>\n",
       "      <td>4.4</td>\n",
       "      <td>100</td>\n",
       "      <td>Biryani,Chinese,North Indian,South Indian</td>\n",
       "      <td>5Th Block</td>\n",
       "      <td>59</td>\n",
       "      <td>Food type/Biryani,Chinese,North Indian,South I...</td>\n",
       "      <td>[0.12830292, 0.14721094, -0.086350575, 0.08263...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Koramangala</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Tunday Kababi</td>\n",
       "      <td>300.0</td>\n",
       "      <td>4.1</td>\n",
       "      <td>100</td>\n",
       "      <td>Mughlai,Lucknowi</td>\n",
       "      <td>5Th Block</td>\n",
       "      <td>56</td>\n",
       "      <td>Food type/Mughlai,Lucknowi#Avg ratings/4.1#Add...</td>\n",
       "      <td>[-0.10582731, 0.15009499, -0.35311985, 0.12081...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Jogupalya</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Kim Lee</td>\n",
       "      <td>650.0</td>\n",
       "      <td>4.4</td>\n",
       "      <td>100</td>\n",
       "      <td>Chinese</td>\n",
       "      <td>Double Road</td>\n",
       "      <td>50</td>\n",
       "      <td>Food type/Chinese#Avg ratings/4.4#Address/Doub...</td>\n",
       "      <td>[-0.09362272, 0.16319357, 0.12415688, 0.012913...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Indiranagar</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>New Punjabi Hotel</td>\n",
       "      <td>250.0</td>\n",
       "      <td>3.9</td>\n",
       "      <td>500</td>\n",
       "      <td>North Indian,Punjabi,Tandoor,Chinese</td>\n",
       "      <td>80 Feet Road</td>\n",
       "      <td>57</td>\n",
       "      <td>Food type/North Indian,Punjabi,Tandoor,Chinese...</td>\n",
       "      <td>[0.12705283, 0.17128171, 0.013174878, 0.239679...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Indiranagar</td>\n",
       "      <td>Bangalore</td>\n",
       "      <td>Nh8</td>\n",
       "      <td>350.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>50</td>\n",
       "      <td>Rajasthani,Gujarati,North Indian,Snacks,Desser...</td>\n",
       "      <td>80 Feet Road</td>\n",
       "      <td>63</td>\n",
       "      <td>Food type/Rajasthani,Gujarati,North Indian,Sna...</td>\n",
       "      <td>[0.08238438, 0.014472998, -0.11513413, 0.28430...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-3af99ccc-6a14-4435-a666-dc6f231b349e')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-3af99ccc-6a14-4435-a666-dc6f231b349e button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-3af99ccc-6a14-4435-a666-dc6f231b349e');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-85d89e21-fecf-4038-aa5e-d2af046be4bb\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-85d89e21-fecf-4038-aa5e-d2af046be4bb')\"\n",
       "            title=\"Suggest charts\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-85d89e21-fecf-4038-aa5e-d2af046be4bb button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "\n",
       "    </div>\n",
       "  </div>\n"
      ],
      "text/plain": [
       "          Area       City         Restaurant  Price  Avg_ratings  \\\n",
       "0  Koramangala  Bangalore        Tandoor Hut  300.0          4.4   \n",
       "1  Koramangala  Bangalore      Tunday Kababi  300.0          4.1   \n",
       "2    Jogupalya  Bangalore            Kim Lee  650.0          4.4   \n",
       "3  Indiranagar  Bangalore  New Punjabi Hotel  250.0          3.9   \n",
       "4  Indiranagar  Bangalore                Nh8  350.0          4.0   \n",
       "\n",
       "   Total_ratings                                          Food_type  \\\n",
       "0            100          Biryani,Chinese,North Indian,South Indian   \n",
       "1            100                                   Mughlai,Lucknowi   \n",
       "2            100                                            Chinese   \n",
       "3            500               North Indian,Punjabi,Tandoor,Chinese   \n",
       "4             50  Rajasthani,Gujarati,North Indian,Snacks,Desser...   \n",
       "\n",
       "        Address  Delivery_time  \\\n",
       "0     5Th Block             59   \n",
       "1     5Th Block             56   \n",
       "2   Double Road             50   \n",
       "3  80 Feet Road             57   \n",
       "4  80 Feet Road             63   \n",
       "\n",
       "                                        query_string  \\\n",
       "0  Food type/Biryani,Chinese,North Indian,South I...   \n",
       "1  Food type/Mughlai,Lucknowi#Avg ratings/4.1#Add...   \n",
       "2  Food type/Chinese#Avg ratings/4.4#Address/Doub...   \n",
       "3  Food type/North Indian,Punjabi,Tandoor,Chinese...   \n",
       "4  Food type/Rajasthani,Gujarati,North Indian,Sna...   \n",
       "\n",
       "                                              vector  \n",
       "0  [0.12830292, 0.14721094, -0.086350575, 0.08263...  \n",
       "1  [-0.10582731, 0.15009499, -0.35311985, 0.12081...  \n",
       "2  [-0.09362272, 0.16319357, 0.12415688, 0.012913...  \n",
       "3  [0.12705283, 0.17128171, 0.013174878, 0.239679...  \n",
       "4  [0.08238438, 0.014472998, -0.11513413, 0.28430...  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = lancedb_table.to_pandas()\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pLEhtZhX5vTr"
   },
   "source": [
    "### Query Transformation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 36
    },
    "id": "mv9NzOea5vTs",
    "outputId": "f1cc4e0a-57cd-4a76-ff2a-5bd5f403af50"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.google.colaboratory.intrinsic+json": {
       "type": "string"
      },
      "text/plain": [
       "'Food type/Biryani,Chinese,North Indian,South Indian#Avg ratings/4.4#Address/5Th Block'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"query_string\"][0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DKGCJRSz5vTs"
   },
   "source": [
    "### Extracting the specifics from the query\n",
    "\n",
    "Just like we pulled out the key details from our CSV to craft query strings, we’ll do the same with user queries. This step is important because it makes searching for the right recommendations much smoother. I mean doing so we can easily run the FTS Index Search."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "9zlQCuSy5vTs",
    "outputId": "0a2124e9-7ec5-4cee-e33d-366499d501d8"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"Food type\": \"Indian or Italian\",\n",
      "  \"Avg ratings\": None,\n",
      "  \"Address\": \"HSR Bangalore\"\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "OPENAI_API_KEY = \"****\"\n",
    "client = OpenAI(api_key=OPENAI_API_KEY)\n",
    "\n",
    "\n",
    "query_string = \"Hi, I am looking for a casual dining restaurant where Indian or Italian food is served near the HSR Bangalore\"\n",
    "\n",
    "# Helper prompt to extract structured data from ip_prompt\n",
    "total_prompt = f\"\"\"Query String: {query_string}\\n\\n\\\n",
    "Now from the query string above extract these following entities pinpoints:\n",
    "1. Food type : Extract the food type\n",
    "2. Avg ratings : Extract the average ratings\n",
    "3. Address : Extract the current exact location, don't consider the fillers like \"near\" or \"nearby\".\n",
    "\n",
    "NOTE : For the Current location, try to understand the pin point location in the query string. Do not give any extra information. If you make the mistakes, bad things\n",
    "will happen.\n",
    "\n",
    "Finally return a python dictionary using those points as keys and don't write the markdown of python. If value of a key is not mentioned, then set it as None.\n",
    "\"\"\"\n",
    "\n",
    "# Make a request to OpenAI's API\n",
    "completion = client.chat.completions.create(\n",
    "    model=\"gpt-4o\",  # Use the appropriate model\n",
    "    store=True,\n",
    "    messages=[{\"role\": \"user\", \"content\": total_prompt}],\n",
    ")\n",
    "\n",
    "# Extract the generated text\n",
    "content = completion.choices[0].message.content\n",
    "print(content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "e-aRJyDl5vTt",
    "outputId": "302894c4-f2c0-4a3f-acf9-076c70188492"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Food type/Indian or Italian#Address/HSR Bangalore\n"
     ]
    }
   ],
   "source": [
    "import ast\n",
    "\n",
    "# Convert the string content to a dictionary\n",
    "try:\n",
    "    response_dict = ast.literal_eval(content)\n",
    "except (ValueError, SyntaxError) as e:\n",
    "    print(\"Error parsing the response:\", e)\n",
    "    response_dict = {}\n",
    "\n",
    "\n",
    "filter_cols = [\"Food type\", \"Avg ratings\", \"Address\"]\n",
    "query_string_parts = [\n",
    "    f\"{col}/{response_dict.get(col)}\" for col in filter_cols if response_dict.get(col)\n",
    "]\n",
    "\n",
    "query_string = \"#\".join(query_string_parts)\n",
    "print((query_string))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Hc5lv7685vTt"
   },
   "source": [
    "### Using LanceDB FTS for searching"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "id": "AF3TVoPx5vTt"
   },
   "outputs": [],
   "source": [
    "# Create the FTS index and search\n",
    "lancedb_table.create_fts_index(\"query_string\", replace=True)\n",
    "results = lancedb_table.search(query_string).to_pandas()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_Hpg2rzL5vTu"
   },
   "source": [
    "### GeoSpatial Recommendation\n",
    "\n",
    "Ok now we will use the Google Geospatial API to pinpoint the exact locations of restaurants and find their coordinates. The next step is to calculate the distance between these restaurants and the user's location. For this, I am going to use the Haversine formula, which uses the coordinates of two points to draw an imaginary straight line between them, measuring the distance across the Earth's surface. There's some math behind how this formula works, but we'll keep things simple and focus on its application for now.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "6M7wLlfO5vTu",
    "outputId": "beaac5bb-30bf-4951-f516-1b758087dbbc"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Restaurant Name: Cafe Azzure\n",
      "Distance: 8.06 km\n",
      "Area: Ashok Nagar\n",
      "Price: 1000.0\n",
      "Coordinates: (12.975012, 77.6076558)\n",
      "Cuisines Type: American,Italian\n",
      "----------------------------------------\n",
      "Restaurant Name: Hyderabad Biryaani House\n",
      "Distance: 8.55 km\n",
      "Area: Victoria Layout\n",
      "Price: 499.0\n",
      "Coordinates: (12.9715987, 77.5945627)\n",
      "Cuisines Type: Indian\n",
      "----------------------------------------\n",
      "Restaurant Name: Aaliyar Ambur Dum Biryani\n",
      "Distance: 7.53 km\n",
      "Area: Ashok Nagar\n",
      "Price: 200.0\n",
      "Coordinates: (12.9694702, 77.60761529999999)\n",
      "Cuisines Type: Indian\n",
      "----------------------------------------\n",
      "Restaurant Name: Jw Kitchen - Jw Marriott\n",
      "Distance: 8.58 km\n",
      "Area: Ashok Nagar\n",
      "Price: 1000.0\n",
      "Coordinates: (12.972231, 77.59495299999999)\n",
      "Cuisines Type: Indian,Continental\n",
      "----------------------------------------\n",
      "Restaurant Name: The Ritz-Carlton - Ganache\n",
      "Distance: 8.55 km\n",
      "Area: Ashok Nagar\n",
      "Price: 1000.0\n",
      "Coordinates: (12.9715987, 77.5945627)\n",
      "Cuisines Type: Indian,Bakery\n",
      "----------------------------------------\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "import math\n",
    "\n",
    "\n",
    "def get_google_geocoding(address, api_key):\n",
    "    base_url = \"https://maps.googleapis.com/maps/api/geocode/json\"\n",
    "    params = {\"address\": address, \"key\": api_key}\n",
    "    response = requests.get(base_url, params=params)\n",
    "\n",
    "    if response.status_code == 200:\n",
    "        result = response.json()\n",
    "        if result[\"status\"] == \"OK\":\n",
    "            latitude = result[\"results\"][0][\"geometry\"][\"location\"][\"lat\"]\n",
    "            longitude = result[\"results\"][0][\"geometry\"][\"location\"][\"lng\"]\n",
    "            return (latitude, longitude)\n",
    "        else:\n",
    "            print(f\"Google API: No results found for address: {address}\")\n",
    "            return None\n",
    "    else:\n",
    "        print(f\"Google API: Request failed for address: {address}\")\n",
    "        return None\n",
    "\n",
    "\n",
    "def haversine(coord1, coord2):\n",
    "    R = 6371.0  # Radius of the Earth in kilometers\n",
    "    lat1, lon1 = map(math.radians, coord1)\n",
    "    lat2, lon2 = map(math.radians, coord2)\n",
    "    dlat = lat2 - lat1\n",
    "    dlon = lon2 - lon1\n",
    "    a = (\n",
    "        math.sin(dlat / 2) ** 2\n",
    "        + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2\n",
    "    )\n",
    "    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))\n",
    "    distance = R * c\n",
    "    return distance\n",
    "\n",
    "\n",
    "def process_top_restaurants(data, current_location, api_key, top_n=5):\n",
    "    current_coords = get_google_geocoding(current_location, api_key)\n",
    "    if not current_coords:\n",
    "        return\n",
    "\n",
    "    for index, row in data.head(top_n).iterrows():\n",
    "        complete_address = f\"{row['Restaurant']}, {row['City']}\"\n",
    "        restaurant_coords = get_google_geocoding(complete_address, api_key)\n",
    "        if restaurant_coords:\n",
    "            distance = haversine(current_coords, restaurant_coords)\n",
    "            print(f\"Restaurant Name: {row['Restaurant']}\")\n",
    "            print(f\"Distance: {distance:.2f} km\")\n",
    "            print(f\"Area: {row['Area']}\")\n",
    "            print(f\"Price: {row['Price']}\")\n",
    "            print(f\"Coordinates: {restaurant_coords}\")\n",
    "            print(f\"Cuisines Type: {row['Food_type']}\")\n",
    "            print(\"-\" * 40)\n",
    "\n",
    "\n",
    "# Example usage\n",
    "GOOGLE_GEOSPATIAL_API_KEY = \"****\"\n",
    "current_location = \"HSR, Bengaluru, India\"\n",
    "process_top_restaurants(results, current_location, GOOGLE_GEOSPATIAL_API_KEY, top_n=5)"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "env",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
